Skip to content

Conversation

r3v5
Copy link
Contributor

@r3v5 r3v5 commented Sep 21, 2025

What does this PR do?

The purpose of this PR is to integrate Prompts API to Responses API to achieve full OpenAI compatibility for current Responses API in Llama Stack.

Closes #3321

Test Plan

Manual API testing and running newly added unit tests.

Prerequisites:
uv run --with llama-stack llama stack build --distro starter --image-type venv --run

API Testing:

  1. Create response with prompt:
curl --request POST \                                                                      
  --url http://localhost:8321/v1/openai/v1/responses \                  
  --header 'Accept: application/json, text/event-stream' \
  --header 'Content-Type: application/json' \
  --data '{
  "input": "What is the capital of Ireland?",
  "model": "openai/gpt-4o",
  "store": true,
  "prompt": {
      "id": "pmpt_dc6c124c7f1393cd4ddb88ed707ffbfd3d937e644d10052c",
      "version": "2",
      "variables": {
          "area_name": "geography",
          "company_name": "Dummy Company"
      }
  }
}'

Output:
{"created_at":1758562266,"error":null,"id":"resp-f20d3abe-d3cf-416b-9060-e653134d51cf","model":"openai/gpt-4o","object":"response","output":[{"content":[{"text":"The capital of Ireland is Dublin.","type":"output_text","annotations":[]}],"role":"assistant","type":"message","id":"msg_67a2f184-ae00-4f49-b4d2-27dfd22623a6","status":"completed"}],"parallel_tool_calls":false,"previous_response_id":null,"prompt":{"prompt":"You are a helpful {{ area_name }} assistant in {{ company_name }}. Always provide accurate information.","version":2,"prompt_id":"pmpt_dc6c124c7f1393cd4ddb88ed707ffbfd3d937e644d10052c","variables":["area_name","company_name"],"is_default":false},"status":"completed","temperature":null,"text":{"format":{"type":"text"}},"top_p":null,"truncation":null,"user":null}%

Telemetry log (only for testing purposes, disabled in final version of the code):

INFO     2025-09-22 18:45:29,366 console_span_processor:62 telemetry:  17:45:27.575 [INFO] Prompt                                                     
         pmpt_dc6c124c7f1393cd4ddb88ed707ffbfd3d937e644d10052c found and applied                                                                      
         Final prompt text: You are a helpful geography assistant in Dummy Company. Always provide accurate information. 
  1. Get current response:
curl --request GET \                                                                                                                                              
  --url http://localhost:8321/v1/openai/v1/responses/resp-f20d3abe-d3cf-416b-9060-e653134d51cf \
  --header 'Accept: application/json'

Output:
{"created_at":1758562266,"error":null,"id":"resp-f20d3abe-d3cf-416b-9060-e653134d51cf","model":"openai/gpt-4o","object":"response","output":[{"content":[{"text":"The capital of Ireland is Dublin.","type":"output_text","annotations":[]}],"role":"assistant","type":"message","id":"msg_67a2f184-ae00-4f49-b4d2-27dfd22623a6","status":"completed"}],"parallel_tool_calls":false,"previous_response_id":null,"prompt":{"prompt":"You are a helpful {{ area_name }} assistant in {{ company_name }}. Always provide accurate information.","version":2,"prompt_id":"pmpt_dc6c124c7f1393cd4ddb88ed707ffbfd3d937e644d10052c","variables":["area_name","company_name"],"is_default":false},"status":"completed","temperature":null,"text":{"format":{"type":"text"}},"top_p":null,"truncation":null,"user":null}%

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Sep 21, 2025
@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch from ef753bc to fe6ea4c Compare September 21, 2025 13:11
Copy link
Collaborator

@mattf mattf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an api change unrelated to how prompts are used in /v1/responses

please review your code assistant output before posting as a PR.

@r3v5
Copy link
Contributor Author

r3v5 commented Sep 22, 2025

this is an api change unrelated to how prompts are used in /v1/responses

please review your code assistant output before posting as a PR.

Hi @mattf ! Could you please elaborate on how the prompts should be used in Responses API in your opinion. My understanding was that they should be propagated to Agent’s messages context as OpenAISystemMessageParam

Copy link
Collaborator

@franciscojavierarceo franciscojavierarceo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @r3v5 it looks like you've suggested adding prompt_id here where you need to add a Prompt object with an id, version, and variables, which would then be consistent with OpenAI's client usage, as outlined here:

response = client.responses.create(
  prompt={
    "id": "pmpt_68b0c29740048196bd3a6e6ac3c4d0e20ed9a13f0d15bf5e",
    "version": "2",
    "variables": {
        "city": "San Francisco",
        "age": 30,
    }
  }
)

So this is currently incorrect. As @mattf suggested, let's make sure we double check this. Thank you.

@r3v5
Copy link
Contributor Author

r3v5 commented Sep 22, 2025

Hey @r3v5 it looks like you've suggested adding prompt_id here where you need to add a Prompt object with an id, version, and variables, which would then be consistent with OpenAI's client usage, as outlined here:

response = client.responses.create(
  prompt={
    "id": "pmpt_68b0c29740048196bd3a6e6ac3c4d0e20ed9a13f0d15bf5e",
    "version": "2",
    "variables": {
        "city": "San Francisco",
        "age": 30,
    }
  }
)

So this is currently incorrect. As @mattf suggested, let's make sure we double check this. Thank you.

Oh yeah, this makes sense. I got it. I will adjust the implementation then

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch from fe6ea4c to a3cdf78 Compare September 22, 2025 17:49
"""

id: str
version: str | None = None
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version has type string because OpenAI has it like string. Reference is here

@mattf
Copy link
Collaborator

mattf commented Sep 23, 2025

@cdoern this is an enhancement to the /openai/v1/responses api, does it match the openai /v1/responses api spec?

@cdoern
Copy link
Contributor

cdoern commented Sep 23, 2025

@mattf:

╰─ oasdiff breaking --fail-on ERR \
docs/_static/llama-stack-spec.yaml \
/Users/charliedoern/Downloads/openapi.documented.yml \
--strip-prefix-base "/v1/openai/v1" \
--match-path '(^/v1/openai/v1/responses.*|^/responses.*)'
51 changes: 24 error, 27 warning, 0 info
error	[api-removed-without-deprecation] at docs/_static/llama-stack-spec.yaml
  in API GET /responses
  	api removed without deprecation

error	[request-body-all-of-added] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	added '#/components/schemas/CreateModelResponseProperties, #/components/schemas/ResponseProperties, subschema #3' to the request body 'allOf' list

error	[request-body-type-changed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	the request's body type/format changed from 'object'/'' to ''/''

error	[response-body-type-changed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	the response's body type/format changed from 'object'/'' to ''/'' for status '200'

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'created_at' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'id' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'model' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'object' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'output' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'parallel_tool_calls' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'status' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the required property 'text' from the response with the '200' status

error	[response-media-type-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API DELETE /responses/{response_id}
  	removed the media type 'application/json' for the response with the status '200'

error	[response-body-type-changed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	the response's body type/format changed from 'object'/'' to ''/'' for status '200'

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'created_at' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'id' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'model' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'object' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'output' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'parallel_tool_calls' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'status' from the response with the '200' status

error	[response-required-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the required property 'text' from the response with the '200' status

error	[request-parameter-default-value-added] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}/input_items
  	for the 'query' request parameter 'limit', default value '20.00' was added

error	[response-property-type-changed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}/input_items
  	the 'object' response's property type/format changed from 'string'/'' to ''/'' for status '200'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'include'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'input'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'instructions'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'max_infer_iters'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'model'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'previous_response_id'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'prompt'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'store'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'stream'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'temperature'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'text'

warning	[request-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the request property 'tools'

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'error' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'previous_response_id' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'prompt' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'temperature' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'top_p' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'truncation' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API POST /responses
  	removed the optional property 'user' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'error' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'previous_response_id' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'prompt' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'temperature' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'top_p' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'truncation' from the response with the '200' status

warning	[response-optional-property-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}
  	removed the optional property 'user' from the response with the '200' status

warning	[request-parameter-removed] at /Users/charliedoern/Downloads/openapi.documented.yml
  in API GET /responses/{response_id}/input_items
  	deleted the 'query' request parameter 'before'
  	This is a warning because some apps may return an error when receiving a parameter that they do not expect. It is recommended to deprecate the parameter first.

there seems to be some breaking changes, BUT these might have existed in main, let me check.

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch from a3cdf78 to d76b15b Compare September 28, 2025 15:01
@franciscojavierarceo
Copy link
Collaborator

hey @cdoern any update on the main branch check here?

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch 2 times, most recently from fadf1d0 to f474e0c Compare September 30, 2025 10:55
@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch 2 times, most recently from 4175600 to f37efb1 Compare October 2, 2025 13:33
@r3v5
Copy link
Contributor Author

r3v5 commented Oct 11, 2025

@r3v5 take a look at my latest changes that handled adding Conversations to responses.

Yeah, I have looked at it already. I guess we need to settle down with your implementation to enable internal deps for agents. I rebased from main already. Right now I enhance other parts of my code

@r3v5
Copy link
Contributor Author

r3v5 commented Oct 11, 2025

@franciscojavierarceo do you think we need to support vars {{ name}}, { { name }} apart from default behaviour like {{name}}?

@franciscojavierarceo
Copy link
Collaborator

I'm not sure, I'd recommend testing those edge cases with OpenAI and seeing their behavior. We should match theirs.

@r3v5
Copy link
Contributor Author

r3v5 commented Oct 11, 2025

I'm not sure, I'd recommend testing those edge cases with OpenAI and seeing their behavior. We should match theirs.

My understanding that they use only placeholders like {{customer_name}}. according to reference. They don't say that there are other types of placeholders.

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch 2 times, most recently from 7f7a3df to 0dcb4df Compare October 11, 2025 20:19
# Replace the variables in the prompt text
# Support all whitespace variations: {{name}}, {{ name }}, {{ name}}, {{name }}, etc.
for name, value in prompt_params.variables.items():
pattern = r"\{\{\s*" + re.escape(name) + r"\s*\}\}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented support for different types of placeholders for variables in prompt. As I said, in OpenAI docs they mention only one type of placeholder (eg. {{variable}}), but I had a chance to create a free prompt in OpenAI playground and it seems they aren't so strict in terms of placeholders. Therefore, at least for now I allowed support for different types of placeholders. Also, I tested it in unit tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you!

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch from 0dcb4df to 82be394 Compare October 11, 2025 20:29
@r3v5
Copy link
Contributor Author

r3v5 commented Oct 11, 2025

I wonder if we need to handle variables with Response input message types like input_image or input_file. See the reference here

  1. ResponseInputImage class by OpenAI
  2. ResponseInputFile class by OpenAI

@r3v5 r3v5 requested a review from mattf October 11, 2025 20:41
@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch 4 times, most recently from a3aba30 to 88b8d3b Compare October 12, 2025 19:40
@r3v5
Copy link
Contributor Author

r3v5 commented Oct 12, 2025

I wonder if we need to handle variables with Response input message types like input_image or input_file. See the reference here

  1. ResponseInputImage class by OpenAI
  2. ResponseInputFile class by OpenAI

I implemented support for two of those as well. Can you, guys PTAL?

Copy link
Collaborator

@leseb leseb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Can you share a workflow example using the Prompt API and re-use that prompt in Responses create? Thanks!

Comment on lines 157 to 159
Path.home() / ".llama" / "files" / path,
Path.cwd() / "files" / path,
Path("/tmp/llama_stack_files") / path,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have to do this? Don't we have a source of truth for that location?

Copy link
Contributor Author

@r3v5 r3v5 Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can add Files API as dependency to OpenAIResponsesImpl and this will allow to easily get the actual path of the file without this workaround. What do you think, @leseb ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try this approach

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought I had replied to see sorry, yes please go ahead with this approach coz the current one feels hacky



@json_schema_type
class OpenAIResponsePromptParam(BaseModel):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we use the type from llama_stack/apis/prompts/prompts.py?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prompt BaseModel in Prompts API has string prompt param and boolean is_default param while OpenAIResponsePromptParam contains exactly three params like id, variables and version like in OpenAI scheme. IMO, having two separate JSON scheme is good in terms of separation of concerns and it allows to achieve full OpenAI compatibility (reference can be found here)

@json_schema_type
class Prompt(BaseModel):
    """A prompt resource representing a stored OpenAI Compatible prompt template in Llama Stack.

    :param prompt: The system prompt text with variable placeholders. Variables are only supported when using the Responses API.
    :param version: Version (integer starting at 1, incremented on save)
    :param prompt_id: Unique identifier formatted as 'pmpt_<48-digit-hash>'
    :param variables: List of prompt variable names that can be used in the prompt template
    :param is_default: Boolean indicating whether this version is the default version for this prompt
    """

    prompt: str | None = Field(default=None, description="The system prompt with variable placeholders")
    version: int = Field(description="Version (integer starting at 1, incremented on save)", ge=1)
    prompt_id: str = Field(description="Unique identifier in format 'pmpt_<48-digit-hash>'")
    variables: list[str] = Field(
        default_factory=list, description="List of variable names that can be used in the prompt template"
    )
    is_default: bool = Field(
        default=False, description="Boolean indicating whether this version is the default version"
    )
@json_schema_type
class OpenAIResponsePromptParam(BaseModel):
    """Prompt object that is used for OpenAI responses.

    :param id: Unique identifier of the prompt template
    :param variables: Dictionary of variable names to OpenAIResponseInputMessageContent structure for template substitution
    :param version: Version number of the prompt to use (defaults to latest if not specified)
    """

    id: str
    variables: dict[str, OpenAIResponseInputMessageContent] | None = None
    version: str | None = None

@r3v5
Copy link
Contributor Author

r3v5 commented Oct 14, 2025

Great work! Can you share a workflow example using the Prompt API and re-use that prompt in Responses create? Thanks!

Thanks, @leseb ! Basically, in PR description I have attached the testing workflow that shows how prompts work in Responses API. But it involves only basic prompts with text variables. Let me know if you want me to show working example with input image and input file variables.

@franciscojavierarceo
Copy link
Collaborator

@r3v5 yeah additional tests/validation would be great with a working example.

@leseb
Copy link
Collaborator

leseb commented Oct 15, 2025

Great work! Can you share a workflow example using the Prompt API and re-use that prompt in Responses create? Thanks!

Thanks, @leseb ! Basically, in PR description I have attached the testing workflow that shows how prompts work in Responses API. But it involves only basic prompts with text variables. Let me know if you want me to show working example with input image and input file variables.

The PR description shows a working example of Prompt inside the Response create, but I'd like to see pmpt_dc6c124c7f1393cd4ddb88ed707ffbfd3d937e644d10052c being taken from a previous call to our internal Prompt API and re-use it in the Response create. Does that make sense? Thanks!

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch 2 times, most recently from d63e31f to b954305 Compare October 16, 2025 12:24
@r3v5 r3v5 changed the title feat: add Prompts API to Responses API feat(responses)!: add Prompts API to Responses API Oct 16, 2025
@franciscojavierarceo
Copy link
Collaborator

@r3v5 unit tests are failing

@r3v5
Copy link
Contributor Author

r3v5 commented Oct 16, 2025

@r3v5 unit tests are failing

I just rebased commit from main today. Still haven't finished my implementation

@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch from b954305 to 1660935 Compare October 16, 2025 20:44
@r3v5 r3v5 force-pushed the add-prompts-api-support-to-responses-api branch from 1660935 to 7a7b2b7 Compare October 16, 2025 20:51
@r3v5
Copy link
Contributor Author

r3v5 commented Oct 16, 2025

Hey @leseb , @franciscojavierarceo !

Here I provide a comprehensive testing of support Prompts in Responses API via curl requests to LLS server.

Test Prompts with Images with text on them in Responses API:

I used this image for testing purposes: iphone 17 image

  1. Upload an image:
curl -X POST http://localhost:8321/v1/files \                                      
  -H "Content-Type: multipart/form-data" \
  -F "file=@/Users/ianmiller/iphone.jpeg" \
  -F "purpose=assistants"

{"object":"file","id":"file-7b52da8206ef42d2b9acd991ec5f1e23","bytes":556241,"created_at":1760646583,"expires_at":1792182583,"filename":"iphone.jpeg","purpose":"assistants"}%

  1. Create prompt:
curl -X POST http://localhost:8321/v1/prompts \                                   
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "You are a product analysis expert. Analyze the following product:\n\nProduct Name: {{product_name}}\nDescription: {{description}}\n\nImage: {{product_photo}}\n\nProvide a detailed analysis including quality assessment, target audience, and pricing recommendations.",
    "variables": ["product_name", "description", "product_photo"]
  }'

{"prompt":"You are a product analysis expert. Analyze the following product:\n\nProduct Name: {{product_name}}\nDescription: {{description}}\n\nImage: {{product_photo}}\n\nProvide a detailed analysis including quality assessment, target audience, and pricing recommendations.","version":1,"prompt_id":"pmpt_e9d108411aaacdc4ea6fbe199a7948fce69bfc826cd43e7f","variables":["product_name","description","product_photo"],"is_default":false}%

  1. Create response:
curl -X POST http://localhost:8321/v1/responses \                                  
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Please analyze this product",
    "model": "openai/gpt-4o",
    "store": true,
    "prompt": {
      "id": "pmpt_e9d108411aaacdc4ea6fbe199a7948fce69bfc826cd43e7f",
      "version": "1",
      "variables": {
        "product_name": {
          "type": "input_text",
          "text": "iPhone 17 Pro Max"
        },
        "description": {
          "type": "input_text",
          "text": "6.9-inch Display, Anti-Reflective Display, 120Hz Refresh rate, Apple A19 Pro chip, 48MP Camera System, 12GB RAM, Titanium Frame, Wi-Fi 7, Launching in 2025"
        },
        "product_photo": {
          "type": "input_image",
          "file_id": "file-7b52da8206ef42d2b9acd991ec5f1e23",
          "detail": "high"
        }
      }
    }
  }'

Output after inferencing:

{"created_at":1760646678,"error":null,"id":"resp_598a00e4-0372-438f-9f00-e0351a222bf4","model":"openai/gpt-4o","object":"response","output":[{"content":[{"text":"## Product Analysis: iPhone 17 Pro Max\n\n### Quality Assessment\n\n**Display:**\n- **Size:** The 6.9-inch display is expansive, catering to users who enjoy media consumption and multitasking.\n- **Anti-Reflective Feature:** This enhances usability in bright environments, making it appealing for outdoor use.\n- **120Hz Refresh Rate:** Ensures smooth scrolling and a more fluid visual experience, beneficial for gaming and video playback.\n\n**Performance:**\n- **Apple A19 Pro Chip:** Likely promises enhanced processing power and efficiency, making it suitable for demanding applications.\n- **12GB RAM:** Supports heavy multitasking and resource-intensive applications, offering a seamless user experience.\n\n**Camera System:**\n- **48MP Triple Camera with Wide, Ultra-Wide, and Telephoto Lenses:** Versatile photography options enabling high-quality images in various settings.\n- **24MP Front Camera:** High-resolution selfies and improved video calls.\n\n**Build:**\n- **Titanium Frame:** Suggests increased durability and a premium feel.\n\n**Connectivity:**\n- **Wi-Fi 7:** Future-proofing the device with the latest connectivity standards for faster internet speeds and better network performance.\n\n### Target Audience\n\n- **Tech Enthusiasts:** Users who prioritize cutting-edge technology and performance.\n- **Professional Photographers and Videographers:** Those who seek high-quality camera systems for mobile photography.\n- **Content Consumers and Creators:** Individuals who watch, create, or edit media extensively on their devices.\n- **Luxury Market:** Users looking for premium materials and design.\n\n### Pricing Recommendations\n\nGiven the high-end features and materials:\n\n- **Premium Segment:** A price range of $1,200 to $1,500 seems appropriate, aligning with market trends for flagship devices from top brands.\n- **Competitive Position:** Ensure it is competitively priced against other flagship models from leading rivals to capture tech-savvy consumers.\n\n### Conclusion\n\nThe iPhone 17 Pro Max appears to set a high bar for mobile technology with its advanced features and premium build. It is likely to appeal to a wide range of high-end users seeking performance, quality, and luxury.","type":"output_text","annotations":[]}],"role":"assistant","type":"message","id":"msg_4a733ec0-d082-47e4-b197-79858e3ad708","status":"completed"}],"parallel_tool_calls":false,"previous_response_id":null,"prompt":{"prompt":"You are a product analysis expert. Analyze the following product:\n\nProduct Name: {{product_name}}\nDescription: {{description}}\n\nImage: {{product_photo}}\n\nProvide a detailed analysis including quality assessment, target audience, and pricing recommendations.","version":1,"prompt_id":"pmpt_e9d108411aaacdc4ea6fbe199a7948fce69bfc826cd43e7f","variables":["product_name","description","product_photo"],"is_default":false},"status":"completed","temperature":null,"text":{"format":{"type":"text"}},"top_p":null,"tools":[],"truncation":null,"usage":{"input_tokens":878,"output_tokens":432,"total_tokens":1310,"input_tokens_details":{"cached_tokens":0},"output_tokens_details":{"reasoning_tokens":0}}}%

The same example but without providing the description of product:

curl -X POST http://localhost:8321/v1/responses \                                 
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Please analyze this product",
    "model": "openai/gpt-4o",
    "store": true,
    "prompt": {
      "id": "pmpt_721d32a4f92124c99cd3fef37cdedeb681afd96597f00cf0",
      "version": "1",
      "variables": {
        "product_name": {
          "type": "input_text",
          "text": "iPhone 17 Pro Max"
        },
        "product_photo": {
          "type": "input_image",
          "file_id": "file-f69a89ddf2d645aeb703cda9f6d8f43f",
          "detail": "high"
        }
      }
    }
  }'

Output:

{"created_at":1760649433,"error":null,"id":"resp_85211c30-c494-410c-9055-518c224ad3d0","model":"openai/gpt-4o","object":"response","output":[{"content":[{"text":"### Product Analysis: iPhone 17 Pro Max\n\n#### Quality Assessment\n\n- **Display:**\n - The 6.9-inch display size is quite large, ideal for media consumption.\n - An anti-reflective display enhances usability in bright environments.\n - A 120Hz refresh rate ensures smooth scrolling and a more responsive touch experience.\n\n- **Performance:**\n - Equipped with the Apple A19 Pro chip, indicating top-tier performance for demanding applications and gaming.\n - 12GB RAM supports heavy multitasking and resource-intensive tasks.\n\n- **Camera System:**\n - Triple 48MP rear cameras (wide, ultra-wide, telephoto) suggest high-quality photography capabilities with versatile options.\n - A 24MP front camera supports excellent selfie and video call quality.\n\n- **Build:**\n - The titanium frame enhances durability while maintaining a premium feel.\n\n- **Connectivity:**\n - Wi-Fi 7 support suggests faster wireless connectivity and future proofing for newer internet standards.\n\n#### Target Audience\n\n- **Tech Enthusiasts:** Individuals desiring cutting-edge technology and who frequently upgrade to the latest devices.\n- **Professional Users:** Those who need a reliable, high-performing device for work-related tasks, including intensive multitasking.\n- **Content Creators:** Users interested in mobile photography and video capabilities due to the advanced camera setup.\n- **Luxury Market:** Consumers looking for a premium smartphone experience with high-end materials like a titanium frame.\n\n#### Pricing Recommendations\n\nGiven the high-end specifications and build quality, the iPhone 17 Pro Max should be positioned in the premium market segment. Pricing should reflect its top-tier status while considering competitors' flagship models. A recommended starting price range could be $1,299 to $1,499, aligning with market expectations for flagship Apple devices with advanced features.\n\n### Conclusion\n\nThe iPhone 17 Pro Max appears to be a powerful and luxurious smartphone poised to satisfy high-end market demands, especially for users prioritizing performance, design, and camera quality.","type":"output_text","annotations":[]}],"role":"assistant","type":"message","id":"msg_590729b1-84bb-4d81-9768-9e6ae512f935","status":"completed"}],"parallel_tool_calls":false,"previous_response_id":null,"prompt":{"prompt":"You are a product analysis expert. Analyze the following product:\n\nProduct Name: {{product_name}}\nImage: {{product_photo}}\n\nProvide a detailed analysis including quality assessment, target audience, and pricing recommendations.","version":1,"prompt_id":"pmpt_721d32a4f92124c99cd3fef37cdedeb681afd96597f00cf0","variables":["product_name","product_photo"],"is_default":false},"status":"completed","temperature":null,"text":{"format":{"type":"text"}},"top_p":null,"tools":[],"truncation":null,"usage":{"input_tokens":825,"output_tokens":406,"total_tokens":1231,"input_tokens_details":{"cached_tokens":0},"output_tokens_details":{"reasoning_tokens":0}}}%

Test Prompts with PDF files in Responses API:

I used this PDF file for testing purposes: invoicesample.pdf

  1. Upload PDF:
curl -X POST http://localhost:8321/v1/files \                                      
  -H "Content-Type: multipart/form-data" \
  -F "file=@/Users/ianmiller/invoicesample.pdf" \
  -F "purpose=assistants"

{"object":"file","id":"file-9575907114944364895e0607b1bb84fc","bytes":149568,"created_at":1760646828,"expires_at":1792182828,"filename":"invoicesample.pdf","purpose":"assistants"}%

  1. Create prompt:
curl -X POST http://localhost:8321/v1/prompts \                                    
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "You are an accounting and financial analysis expert. Analyze the following invoice document:\n\nInvoice Document: {{invoice_doc}}\n\nProvide a comprehensive analysis",
    "variables": ["invoice_doc"]
  }'

{"prompt":"You are an accounting and financial analysis expert. Analyze the following invoice document:\n\nInvoice Document: {{invoice_doc}}\n\nProvide a comprehensive analysis","version":1,"prompt_id":"pmpt_3d276c04719f06eb90077733a9a9c9d792031d2f62ceed42","variables":["invoice_doc"],"is_default":false}%

  1. Create response:
curl -X POST http://localhost:8321/v1/responses \                                  
  -H "Content-Type: application/json" \
  -d '{
    "input": "Please provide a detailed analysis of this invoice",
    "model": "openai/gpt-4o",
    "store": true,
    "prompt": {
      "id": "pmpt_3d276c04719f06eb90077733a9a9c9d792031d2f62ceed42",
      "version": "1",
      "variables": {
        "invoice_doc": {
          "type": "input_file",
          "file_id": "file-9575907114944364895e0607b1bb84fc",
          "filename": "invoicesample.pdf"
        }
      }
    }
  }'

Output after inferencing:

{"created_at":1760646886,"error":null,"id":"resp_b7adc30e-8313-4818-afc7-6000ff57e193","model":"openai/gpt-4o","object":"response","output":[{"content":[{"text":"Here's a comprehensive analysis of the invoice provided:\n\n### Invoice Details:\n\n- **Recipient:** Denny Gunawan\n- **Recipient Address:** 221 Queen St, Melbourne VIC 3000\n- **Supplier Address:** 123 Somewhere St, Melbourne VIC 3000\n- **Contact Number:** (03) 1234 5678\n- **Invoice Number:** #20130304\n\n### Items Listed:\n\n1. **Apple**\n - Price per kg: $5.00\n - Quantity: 1 kg\n - Subtotal: $5.00\n\n2. **Orange**\n - Price per kg: $1.99\n - Quantity: 2 kg\n - Subtotal: $3.98\n\n3. **Watermelon**\n - Price per kg: $1.69\n - Quantity: 3 kg\n - Subtotal: $5.07\n\n4. **Mango**\n - Price per kg: $9.56\n - Quantity: 2 kg\n - Subtotal: $19.12\n\n5. **Peach**\n - Price per kg: $2.99\n - Quantity: 1 kg\n - Subtotal: $2.99\n\n### Financial Summary:\n\n- **Subtotal:** $36.00\n- **GST (10%):** $3.60\n- **Total:** $39.60\n\n### Additional Observations:\n\n- **GST Calculation:** The GST is calculated at 10% of the subtotal, which aligns with typical Australian tax rates.\n- **Supplier Logo:** The invoice features a logo at the top of the document indicating the business name \"Sunny Farm\" with the tagline \"Naturally Fresh Produce - Victoria\".\n- **Decoration:** There's a \"Thank You\" note at the bottom, adding a customer-friendly touch.\n- **Miscellaneous Text:** Contains placeholder text (\"Lorem ipsum...\"), suggesting potential space for additional terms or messages.\n\n### Conclusion:\n\nThe invoice is clearly structured, providing detailed information about each item purchased, quantities, pricing, and tax details. The GST is accurately applied, and the design includes space for branding and customer relation elements. The inclusion of placeholder text hints at customization or further information typically present in full invoices. \n\nOverall, it is representative of a business that focuses on providing organic produce, likely maintaining standardized procedures for documenting sales and taxes.","type":"output_text","annotations":[]}],"role":"assistant","type":"message","id":"msg_0ccb6c2e-cb1d-4ec6-8cd2-0744c1dade07","status":"completed"}],"parallel_tool_calls":false,"previous_response_id":null,"prompt":{"prompt":"You are an accounting and financial analysis expert. Analyze the following invoice document:\n\nInvoice Document: {{invoice_doc}}\n\nProvide a comprehensive analysis","version":1,"prompt_id":"pmpt_3d276c04719f06eb90077733a9a9c9d792031d2f62ceed42","variables":["invoice_doc"],"is_default":false},"status":"completed","temperature":null,"text":{"format":{"type":"text"}},"top_p":null,"tools":[],"truncation":null,"usage":{"input_tokens":529,"output_tokens":486,"total_tokens":1015,"input_tokens_details":{"cached_tokens":0},"output_tokens_details":{"reasoning_tokens":0}}}%

Test simple text Prompt in Responses API:

  1. Create prompt:
 curl -X POST http://localhost:8321/v1/prompts \                                    
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Hello {{name}}! You are working at {{company}}. Your role is {{role}} at {{company}}. Remember, {{name}}, to be {{tone}}.",
    "variables": ["name", "company", "role", "tone"]
  }'

{"prompt":"Hello {{name}}! You are working at {{company}}. Your role is {{role}} at {{company}}. Remember, {{name}}, to be {{tone}}.","version":1,"prompt_id":"pmpt_60d390fd55948e03803dbea7dfad034709a2a75214104b82","variables":["name","company","role","tone"],"is_default":false}%

  1. Create response:
curl -X POST http://localhost:8321/v1/responses \                                  
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "What is the capital of Ireland?",
    "model": "openai/gpt-4o",
    "store": true,
    "prompt": {
      "id": "pmpt_60d390fd55948e03803dbea7dfad034709a2a75214104b82",
      "version": "1",
      "variables": {
        "name": {
          "type": "input_text",
          "text": "Alice"
        },
        "company": {
          "type": "input_text",
          "text": "Dummy Company"
        },
        "role": {
          "type": "input_text",
          "text": "Geography expert"
        },
        "tone": {
          "type": "input_text",
          "text": "professional and helpful"
        }
      }
    }
  }'

Output after inferencing:

{"created_at":1760647144,"error":null,"id":"resp_be7b207c-29d0-4cba-b583-a240fe010b70","model":"openai/gpt-4o","object":"response","output":[{"content":[{"text":"The capital of Ireland is Dublin. If you have any more questions about Ireland or need further geographical assistance, feel free to ask!","type":"output_text","annotations":[]}],"role":"assistant","type":"message","id":"msg_4a71ede8-2e6d-4e9b-8637-b2a69ca21734","status":"completed"}],"parallel_tool_calls":false,"previous_response_id":null,"prompt":{"prompt":"Hello {{name}}! You are working at {{company}}. Your role is {{role}} at {{company}}. Remember, {{name}}, to be {{tone}}.","version":1,"prompt_id":"pmpt_60d390fd55948e03803dbea7dfad034709a2a75214104b82","variables":["name","company","role","tone"],"is_default":false},"status":"completed","temperature":null,"text":{"format":{"type":"text"}},"top_p":null,"tools":[],"truncation":null,"usage":{"input_tokens":47,"output_tokens":26,"total_tokens":73,"input_tokens_details":{"cached_tokens":0},"output_tokens_details":{"reasoning_tokens":0}}}%

@r3v5 r3v5 requested a review from leseb October 16, 2025 21:12
@r3v5
Copy link
Contributor Author

r3v5 commented Oct 16, 2025

@r3v5 unit tests are failing

I just rebased commit from main today. Still haven't finished my implementation

The implementation is there :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Prompts API support to Responses API

5 participants